﻿using Microsoft.AspNetCore.Builder;
using Serilog;
using Serilog.Configuration;
using Serilog.Events;
using Serilog.Filters;
using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.Service.System;
using WMS.FC.Infrastructure.Filter;

namespace WMS.FC.Infrastructure.Register
{
    public static class SerilogRegister
    {
        public const string LogTemplate = "日志时间:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}{Message}{NewLine}{NewLine}";
        public const long FileSizeLimitBytes = 524288000;

        public static void RegisterSerilog(this WebApplicationBuilder builder, WmsSettings wmsSettings)
        {
            Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore.Database.Command")).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"DB\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource("Microsoft.EntityFrameworkCore")).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"DB\Error\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource("Oracle.ManagedDataAccess.Client")).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"DB\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource("Oracle.ManagedDataAccess.Client")).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"DB\Error\log_.log")))

                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ServiceBase>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Debug).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"Service\Debug\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ServiceBase>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"Service\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ServiceBase>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"Service\Error\log_.log")))

                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WMSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Debug).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WMS\Debug\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WMSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WMS\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WMSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WMS\Error\log_.log")))

                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WCSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Debug).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WCS\Debug\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WCSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WCS\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<WCSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"WCS\Error\log_.log")))

                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ECSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Debug).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"ECS\Debug\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ECSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Information).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"ECS\Information\log_.log")))
                    .WriteTo.Logger(config => config.Filter.ByIncludingOnly(Matching.FromSource<ECSFilter>()).Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Error).WriteTo.File(Path.Combine(wmsSettings.LogDirectory, @"ECS\Error\log_.log")))

                    .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information)
                    .CreateLogger();

            builder.Host.UseSerilog();
        }

        private static LoggerConfiguration File(this LoggerSinkConfiguration sinkConfiguration, string path)
        {
            return sinkConfiguration.File(path: path, fileSizeLimitBytes: FileSizeLimitBytes, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day, outputTemplate: LogTemplate, retainedFileTimeLimit: TimeSpan.FromDays(30));
        }
    }
}
